﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AutoPartsSearch.Domain.Concrete;
using AutoPartsSearch.Domain.Concrete.Mappers;
using AutoPartsSearch.Domain.Entities.Messages;
using AutoPartsSearch.Web.Infrastructure.Concrete;
using Griffin.MvcContrib.Localization.Types;
using Griffin.MvcContrib.SqlServer;
using Griffin.MvcContrib.SqlServer.Localization;
using Ninject;
using AutoPartsSearch.Domain.Abstract.Repositories;
using Moq;
using AutoPartsSearch.Domain.Entities;
using AutoPartsSearch.Domain.Concrete.Repositories;
using AutoPartsSearch.Domain.Abstract;
using AutoPartsSearch.Domain.Common;
using AutoPartsSearch.Domain.Fake;
using Griffin.MvcContrib.Localization.Views;

namespace AutoPartsSearch.Web.Infrastructure
{
    public class NinjectControllerFactory : DefaultControllerFactory, IDependencyResolver
    {
        private IKernel _ninjectKernel;

        public NinjectControllerFactory()
        {
            this._ninjectKernel = new StandardKernel();
            AddBindings();
            RegisterLocalizationFetures();
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            return controllerType == null 
                ? null 
                : (IController)this._ninjectKernel.Get(controllerType);
        }

        private void AddBindings()
        {
            this._ninjectKernel.Bind<IDbContext>().To<DbContext>();
            this._ninjectKernel.Bind<ISellerRepository>().To<DapperSellerRepository>();
            this._ninjectKernel.Bind<ISearchQueryRepository>().To<DapperSearchQueryRepository>();
            this._ninjectKernel.Bind<IDictionaryRepository>().To<DapperDictionaryRepository>().WhenInjectedInto<Cache.Repositories.DictionaryRepository>();
            this._ninjectKernel.Bind<IDictionaryRepository>().To<DapperDictionaryRepository>().WhenInjectedInto<Areas.Administration.Controllers.DictionaryController>();
            this._ninjectKernel.Bind<IDictionaryRepository>().To<Cache.Repositories.DictionaryRepository>();
            this._ninjectKernel.Bind<ILanguageGetter>().To<SessionLanguageGetter>();
            this._ninjectKernel.Bind<ISellerSearchQueryRepository>().To<DapperSellerSearchQueryRepository>();
            this._ninjectKernel.Bind<ISellerGetter>().To<SellerGetter>();
            this._ninjectKernel.Bind<IMessageSender>().To<SmtpMessageSender>();
            this._ninjectKernel.Bind<IMapper<SearchQuery, Message>>().To<SearchQueryToMessageMapper>();
            this._ninjectKernel.Bind<IMapper<Seller, Recipient>>().To<SellerToRecipientMapper>();
            this._ninjectKernel.Bind<IConfigurationGetter>().To<ConfigurationManagerGetter>().InSingletonScope();
            this._ninjectKernel.Bind<IMessageBuilder>().To<MessageBuilder>();
            this._ninjectKernel.Bind<ISearchQueryProcessor>().To<SearchQueryProcessor>();
            this._ninjectKernel.Bind<IOfferProcessor>().To<OfferProcessor>();
            this._ninjectKernel.Bind<IBlackListRepository>().To<DapperBlackListRepository>();
            this._ninjectKernel.Bind<IMembership>().To<AspNetMembership>();
            this._ninjectKernel.Bind<IContactRepository>().To<DapperContactRepository>();
            this._ninjectKernel.Bind<IOfferRepository>().To<DapperOfferRepository>();
        }

        private void RegisterLocalizationFetures()
        {
            this._ninjectKernel.Bind<ViewLocalizer>().ToSelf();
            this._ninjectKernel.Bind<ILocalizedTypesRepository>().To<Cache.Localizations.LocalizedTypeRepository>();
            this._ninjectKernel.Bind<ITypePromptImporter>().To<Cache.Localizations.LocalizedTypeRepository>();
            this._ninjectKernel.Bind<IViewLocalizationRepository>().To<Cache.Localizations.LocalizedViewsRepository>();
            this._ninjectKernel.Bind<IViewPromptImporter>().To<Cache.Localizations.LocalizedViewsRepository>();
            this._ninjectKernel.Bind<ILocalizedStringProvider>().To<RepositoryStringProvider>();

            this._ninjectKernel.Bind<AdoNetConnectionFactory>().ToConstructor(
                x => new AdoNetConnectionFactory("AutoPartsDB"));
            this._ninjectKernel.Bind<ILocalizationDbContext>().To<LocalizationDbContext>();
        }


        public object GetService(Type serviceType)
        {
            return this._ninjectKernel.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return this._ninjectKernel.GetAll(serviceType);
        }
    }
}